# -*- coding: utf-8 -*-
from rest_framework.decorators import action
from core.viewset import CustomModelViewSet
from core.response import JsonResponse
from .models import Product
from .serializers import *
from .resources import *
from .filters import *
from apps.tms.models import TestCase
from apps.pms.models import Requirement, Version, Module


class ProductViewSet(CustomModelViewSet):
    """
    产品管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = Product.objects.all()
    list_serializer_class = ListProductSerializer
    serializer_class = ProductSerializer
    filterset_class = ProductFilterSet
    import_resources = ImportProductResources
    export_resources = ExportProductResources

    @action(detail=True, methods=["PUT"])
    def sync(self, request, pk=None, *args, **kwargs):
        product = self.get_object()
        target_product = Product.objects.get(id=request.data.get("target"))
        items = request.data.get("items")
        for item in items:
            if item.get("type") == "Requirement" and item.get("parent") == None:
                sync_item(item, product, target_product)
        return JsonResponse(data=[], msg="同步成功")


def sync_item(item, product, target_product, parent_requirement=None):
    if item.get("type") == "Requirement":
        new_requirement = sync_requirement(
            node=item, product=product, parent_requirement=parent_requirement
        )
    elif item.get("type") == "TestCase":
        if parent_requirement is not None:
            sync_testcase(
                node=item,
                product=product,
                module=parent_requirement.module,
                requirement=parent_requirement,
                target_product=target_product,
            )

    children = item.get("children", [])
    for child in children:
        sync_item(
            child,
            product,
            target_product,
            (
                new_requirement
                if item.get("type") == "Requirement"
                else parent_requirement
            ),
        )


def sync_requirement(node, product, parent_requirement):
    requirement = Requirement.objects.get(id=node.get("id"))
    new_module = sync_module(product=product, module=requirement.module)
    new_version = sync_version(product=product, version=requirement.version)
    defaults = {
        "origin": requirement.origin,
        "classify": requirement.classify,
        "priority": requirement.priority,
        "desc": requirement.desc,
        "criteria": requirement.criteria,
        "owner": requirement.owner,
        "status": "draft",
        "module": new_module,
        "version": new_version,
        "parent": parent_requirement,
    }
    new_requirement, _ = Requirement.objects.update_or_create(
        name=requirement.name, product=product, defaults=defaults
    )
    reviewer_ids = list(requirement.reviewers.values_list("id", flat=True))
    new_requirement.reviewers.set(reviewer_ids)
    new_requirement.save()
    return new_requirement


def sync_testcase(node, product, module, requirement, target_product):
    testcase = TestCase.objects.get(id=node.get("id"))
    if not module:
        module = sync_module(product=product, module=testcase.module)
    defaults = {
        "module": module,
        "name": testcase.name,
        "level": testcase.level,
        "type": testcase.type,
        "stage": testcase.stage,
        "isauto": testcase.isauto,
        "description": testcase.description,
        "precondition": testcase.precondition,
        "steps": testcase.steps,
        "script": testcase.script,
    }
    number = testcase.number.replace(target_product.number, product.number)
    new_testcase, _ = TestCase.objects.update_or_create(
        product=product, name=testcase.name, number=number, defaults=defaults
    )
    new_testcase.reqs.add(requirement.id)
    new_testcase.save()


def sync_module(product, module):
    if not module:
        return None
    # 递归处理父模块
    parent_module = sync_module(product, module.parent) if module.parent else None
    # 创建或获取当前模块及其父模块的引用
    return Module.objects.get_or_create(
        product=product,
        name=module.name,
        number=module.number,
        parent=parent_module,
    )[0]


def sync_version(product, version):
    if not version:
        return None
    # 递归处理父版本
    parent_version = sync_version(product, version.parent) if version.parent else None
    # 创建或获取当前版本并引用其父版本
    return Version.objects.get_or_create(
        product=product,
        name=version.name,
        parent=parent_version,
    )[0]
